"""Contains networking code for TTT.

FUNCTIONS:
    NetGame(game) -- Takes in either a TTTServer or TTTClient object and begins
        game loop.  Handles accepting moves and making proper method calls.

    ServerGame() -- Starts a game with the current interpreter as the server.

    ClientGame() -- Starts a game with current interpreter as the client.


CLASSES:
    TTTNet(Logfile.Log) -- Basic object for networking.  Has methods for making
        moves.
        sendMove(x,y) -- Makes move and then sends it over the network.
        receiveMove() -- Receives a move over the network and makes it.

    TTTServer(TTTNet) -- Server object.
        start() -- Starts server by creating appropriate sockets.
        end() -- Closes sockets appropriately.

    TTTClient(TTTNet) -- Client object.
        start(server) -- Creates socket to server.
        end() -- Closes sockets.

"""
import Logfile
from Exc import *
import socket, traceback, sys

class TTTNet(Logfile.Log):
    """Basic object containing methods for making network-aware moves and
    receiving moves."""
    def sendMove(self, x, y):
        """Makes move locally and then sends it to opponent."""
        print 'Making move %s,%s' % (x,y)
        self.Move(self.Human, x, y)
        move='%s %s' % (x,y)
        print 'Sending move -- (%s)' % move
        self.sock.send(move)
        print 'Sent'

    def receiveMove(self):
        """Receives move from opponent and stores it."""
        print 'Receving move...'
        move=self.sock.recv(10)
        print 'Received --(%s)' % move
        self.Move(self.Comp,int(move[0]),int(move[2]))



class TTTServer(TTTNet):
    """Server object implementing methods for starting and shutting down a server."""
    def start(self):
        """Starts server."""
        self.server_sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_sock.bind(('127.0.0.1',5007))
        self.server_sock.listen(1)
        self.sock, self.other_address=self.server_sock.accept()

    def end(self):
        """Shuts down server."""
        self.sock.close()



class TTTClient(TTTNet):
    """Client object with methods for starting and shutting down a client."""
    def start(self,server):
        """Starts client."""
        self.human='O'
        self.comp='X'
        self.sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        self.sock.connect((server,5007))

    def end(self):
        """Shuts down client."""
        print 'Closing socket...'
        self.sock.close()



def NetGame(game):
    """Game loop"""
    try:
        while 1:
            Pos=raw_input('\n\n\nPlease make a move (you are %s):' % game.Human)
            if Pos == '7': game.sendMove(0, 0)  
            elif Pos == '8': game.sendMove(0, 1)
            elif Pos == '9': game.sendMove(0, 2)
            elif Pos == '4': game.sendMove(1, 0)
            elif Pos == '5': game.sendMove(1, 1)
            elif Pos == '6': game.sendMove(1, 2)
            elif Pos == '1': game.sendMove(2, 0)
            elif Pos == '2': game.sendMove(2, 1)
            elif Pos == '3': game.sendMove(2, 2)
            else: raise IllegalMove
            game.CheckWin()
            game.CatsGame()
            game.Display()

            print
            print
            print
            print 'Waiting for move from opponent...'
            game.receiveMove()
            print 'Move received.'
            game.CheckWin()
            game.CatsGame()
            game.Display()
            
    except Winner:
        game.Display()
        print
        print 'Winner!'
        game.end()
        game.Save('Winner')
    except IllegalMove:
        game.end()
        game.Save('IllegalMove')
    except CatsGame:
        game.Display()
        print
        print 'Cat\'s Game!'
        game.end()
        game.Save('CatsGame')
    except IllegalRep:
        print
        print 'Illegal choice of character representation'
        game.end()
        game.Save('IllegalRep')
    except ExitProg:
        print 'Exiting program'
        raise
    except:
        game.end()
        print 'Built-in Exception'
        game.Save('Built-in Exception')
        raise


def ServerGame():
    """Beginning server info."""
    print 'Your IP address is', socket.gethostbyname(socket.gethostname())
    print 'You will be \'X\''
    print
    print 'Waiting for a connection on port 5007...'
    game=TTTServer()
    game.start()
    print 'Connection received from',game.other_address
    print
    print
    print
    NetGame(game)


def ClientGame():
    """Beginning client info."""
    print 'Your IP address is', socket.gethostbyname(socket.gethostname())
    print 'You will be \'O\''
    print
    server=raw_input('Enter the IP address of the TTT server you would like to connect to: ')
    game=TTTClient()
    print 'Attempting to connect on port 5007...'
    game.start(server)
    print 'Connection made to',game.sock.getpeername()
    print
    print
    print
    print 'Waiting for move from opponent...'
    game.receiveMove()
    print 'Move received.'
    game.CheckWin()
    game.CatsGame()
    game.Display()
    NetGame(game)



if __name__=='__main__':
    response=raw_input('Would you like to be a client or server?: ')
    if response=='server': ServerGame()
    else: ClientGame()
